package com.sanyue.codingsettlement.service.impl;
import java.util.Date;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sanyue.codingsettlement.common.ErrorCode;
import com.sanyue.codingsettlement.constant.CommonConstant;
import com.sanyue.codingsettlement.exception.BusinessException;
import com.sanyue.codingsettlement.exception.ThrowUtils;
import com.sanyue.codingsettlement.mapper.UserTeamMapper;
import com.sanyue.codingsettlement.model.dto.userteam.UserJoinTeamRequest;
import com.sanyue.codingsettlement.model.dto.userteam.UserTeamQueryRequest;
import com.sanyue.codingsettlement.model.entity.Team;
import com.sanyue.codingsettlement.model.entity.UserTeam;
import com.sanyue.codingsettlement.model.entity.User;
import com.sanyue.codingsettlement.model.enums.TeamStatusEnum;
import com.sanyue.codingsettlement.model.vo.UserVO;
import com.sanyue.codingsettlement.service.TeamService;
import com.sanyue.codingsettlement.service.UserTeamService;
import com.sanyue.codingsettlement.service.UserService;
import com.sanyue.codingsettlement.utils.SqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户队伍关联表服务实现
 *
 * @author <a href="https://github.com/liyupi">程序员鱼皮</a>
 * @from <a href="https://www.code-nav.cn">编程导航学习圈</a>
 */
@Service
@Slf4j
public class UserTeamServiceImpl extends ServiceImpl<UserTeamMapper, UserTeam> implements UserTeamService {

    @Resource
    private UserService userService;


    @Resource
    private TeamService teamService;

    /**
     * 校验数据
     *
     * @param userTeam
     * @param add      对创建的数据进行校验
     */
    @Override
    public void validUserTeam(UserTeam userTeam, boolean add) {
        ThrowUtils.throwIf(userTeam == null, ErrorCode.PARAMS_ERROR);
        // todo 从对象中取值
        Long userId = userTeam.getUserId();
        Long teamId = userTeam.getTeamId();
        // 创建数据时，参数不能为空
        if (add) {
            // todo 补充校验规则
            ThrowUtils.throwIf(userId == null, ErrorCode.PARAMS_ERROR);
            ThrowUtils.throwIf(teamId == null, ErrorCode.PARAMS_ERROR);
        }
    }

    /**
     * 获取查询条件
     *
     * @param userTeamQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<UserTeam> getQueryWrapper(UserTeamQueryRequest userTeamQueryRequest) {
        QueryWrapper<UserTeam> queryWrapper = new QueryWrapper<>();
        if (userTeamQueryRequest == null) {
            return queryWrapper;
        }
        // todo 从对象中取值
        Long id = userTeamQueryRequest.getId();
        Long userId = userTeamQueryRequest.getUserId();
        Long teamId = userTeamQueryRequest.getTeamId();
        String sortField = userTeamQueryRequest.getSortField();
        String sortOrder = userTeamQueryRequest.getSortOrder();
        // todo 补充需要的查询条件

        // 精确查询
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "userId", userId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(teamId), "teamId", teamId);
        // 排序规则
        queryWrapper.orderBy(SqlUtils.validSortField(sortField),
                sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }

    /**
     * 用户加入队伍
     *
     * @param userTeam
     * @return
     */
    @Override
    public long userJoinTeam(UserJoinTeamRequest userJoinTeamRequest, User loginUser) {
        // 1. 参数校验
        //   a. 队伍是否存在
        Long teamId = userJoinTeamRequest.getTeamId();
        Long userId = loginUser.getId();
        String password = userJoinTeamRequest.getPassword();
        Team team = teamService.getById(teamId);
        ThrowUtils.throwIf(team == null,ErrorCode.PARAMS_ERROR,"队伍不存在");
        //   b. 用户是否已经加入队伍
        QueryWrapper<UserTeam> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId",userId);
        queryWrapper.eq("teamId",teamId);
        ThrowUtils.throwIf(this.count(queryWrapper) > 0,ErrorCode.PARAMS_ERROR,"您已加入该队伍");
        //   c. 队伍的人数是否已满
        queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("teamId",teamId);
        ThrowUtils.throwIf(this.count(queryWrapper) > team.getMaxNumber(),ErrorCode.PARAMS_ERROR,"队伍人数已满");
        //   d. 队伍的状态
        //     ⅰ. 私有状态：不可加入
        ThrowUtils.throwIf(TeamStatusEnum.PRIVATE.getValue().equals(team.getStatus()),ErrorCode.PARAMS_ERROR,"私有队伍不可加入");
        //     ⅲ. 加密状态：需要输入密码后才能加入
        //       1. 密码校验
        if (TeamStatusEnum.ENCRYPT.getValue().equals(team.getStatus())){
            ThrowUtils.throwIf(StringUtils.isBlank(password),ErrorCode.PARAMS_ERROR,"密码格式错误，为空");
            ThrowUtils.throwIf(!team.getPassword().equals(password),ErrorCode.PARAMS_ERROR,"密码错误");
        }
        //      ⅱ. 正常状态：所有用户均可以加入
        UserTeam userTeam = new UserTeam();
        userTeam.setUserId(userId);
        userTeam.setTeamId(teamId);
        boolean save = this.save(userTeam);
        ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR);
        return userTeam.getTeamId();
    }

    @Override
    @Transactional
    public boolean userExitTeam(long teamId, User loginUser) {
        //2. 队伍是否存在
        Team team = teamService.getById(teamId);
        ThrowUtils.throwIf(team == null,ErrorCode.PARAMS_ERROR,"队伍不存在");
        // 3. 用户是否已经加入队伍
        Long userId = loginUser.getId();
        QueryWrapper<UserTeam> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId",userId);
        queryWrapper.eq("teamId",teamId);
        long count = this.count(queryWrapper);
        ThrowUtils.throwIf(count == 0,ErrorCode.PARAMS_ERROR,"您未加入该队伍");
        // 4. 队伍还剩几人
        QueryWrapper<UserTeam> qw = new QueryWrapper<>();
        qw.eq("teamId",teamId);
        count = this.count(qw);
        //   a. 如果队伍只剩一人，则解散队伍
        if(count == 1){
            boolean remove = this.remove(qw);
            if(!remove){
                throw new BusinessException(ErrorCode.OPERATION_ERROR);
            }
            return teamService.removeById(teamId);
        }
        //   b. 如果队伍还剩多人
        //     ⅰ. 用户是队伍创建者，将队长权限转交给第二个加入队伍的人
        //     ⅱ. 如果是普通用户，直接退出
        if(team.getUserId().equals(userId) ){
            qw = new QueryWrapper<>();
            qw.eq("teamId",teamId);
            qw.orderByAsc("joinTime");
            UserTeam userTeam = this.list(qw).get(1);
            System.out.println(userTeam.getUserId());
            team.setUserId(userTeam.getUserId());
            teamService.updateById(team);
        }
        return this.remove(queryWrapper);
    }

    // /**
    //  * 获取用户队伍关联表封装
    //  *
    //  * @param userTeam
    //  * @param request
    //  * @return
    //  */
    // @Override
    // public UserTeamVO getUserTeamVO(UserTeam userTeam, HttpServletRequest request) {
    //     // 对象转封装类
    //     UserTeamVO userTeamVO = UserTeamVO.objToVo(userTeam);
    //
    //     // todo 可以根据需要为封装对象补充值，不需要的内容可以删除
    //     // region 可选
    //     // 1. 关联查询用户信息
    //     Long userId = userTeam.getUserId();
    //     User user = null;
    //     if (userId != null && userId > 0) {
    //         user = userService.getById(userId);
    //     }
    //     UserVO userVO = userService.getUserVO(user);
    //     userTeamVO.setUser(userVO);
    //
    //     // endregion
    //
    //     return userTeamVO;
    // }
    //
    // /**
    //  * 分页获取用户队伍关联表封装
    //  *
    //  * @param userTeamPage
    //  * @param request
    //  * @return
    //  */
    // @Override
    // public Page<UserTeamVO> getUserTeamVOPage(Page<UserTeam> userTeamPage, HttpServletRequest request) {
    //     List<UserTeam> userTeamList = userTeamPage.getRecords();
    //     Page<UserTeamVO> userTeamVOPage = new Page<>(userTeamPage.getCurrent(), userTeamPage.getSize(), userTeamPage.getTotal());
    //     if (CollUtil.isEmpty(userTeamList)) {
    //         return userTeamVOPage;
    //     }
    //     // 对象列表 => 封装对象列表
    //     List<UserTeamVO> userTeamVOList = userTeamList.stream().map(userTeam -> {
    //         return UserTeamVO.objToVo(userTeam);
    //     }).collect(Collectors.toList());
    //
    //     // todo 可以根据需要为封装对象补充值，不需要的内容可以删除
    //     // region 可选
    //     // 1. 关联查询用户信息
    //     Set<Long> userIdSet = userTeamList.stream().map(UserTeam::getUserId).collect(Collectors.toSet());
    //     Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
    //             .collect(Collectors.groupingBy(User::getId));
    //     // 2. 已登录，获取用户点赞、收藏状态
    //     Map<Long, Boolean> userTeamIdHasThumbMap = new HashMap<>();
    //     Map<Long, Boolean> userTeamIdHasFavourMap = new HashMap<>();
    //     User loginUser = userService.getLoginUserPermitNull(request);
    //     // 填充信息
    //     userTeamVOList.forEach(userTeamVO -> {
    //         Long userId = userTeamVO.getUserId();
    //         User user = null;
    //         if (userIdUserListMap.containsKey(userId)) {
    //             user = userIdUserListMap.get(userId).get(0);
    //         }
    //         userTeamVO.setUser(userService.getUserVO(user));
    //     });
    //     // endregion
    //
    //     userTeamVOPage.setRecords(userTeamVOList);
    //     return userTeamVOPage;
    // }

}
